using Microsoft.Win32;
using System.Windows.Forms;
using System.Drawing;

/*
 * Copyright (c) 2007-2011, PerformanceDude.com (infoatperformancedude.com), Lex Li (supportatlextm.com), Rami Abughazaleh (rami.abughazalehatgmail.com)
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of PerformanceDude.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
namespace PerformanceDude.MSBuildShellExtension.Loggers.ErrorListLogger
{
  public class PersistWindowState : System.ComponentModel.Component
  {
    // event info that allows form to persist extra window state data
    public delegate void WindowStateDelegate(object sender, RegistryKey key);
    public event WindowStateDelegate LoadStateEvent;
    public event WindowStateDelegate SaveStateEvent;

    private ErrorListForm m_parent;
    private string m_regPath;
    private int m_normalLeft;
    private int m_normalTop;
    private int m_normalWidth;
    private int m_normalHeight;
    private FormWindowState m_windowState;
    private bool m_allowSaveMinimized = false;

    public ErrorListForm Parent
    {
      set
      {
        m_parent = value;

        // subscribe to parent form's events
        m_parent.Closing += OnClosing;
        m_parent.Resize += OnResize;
        m_parent.Move += OnMove;
        m_parent.Load += OnLoad;

        // get initial width and height in case form is never resized
        m_normalWidth = m_parent.Width;
        m_normalHeight = m_parent.Height;
      }
      get
      {
        return m_parent;
      }
    }

    // registry key should be set in parent form's constructor
    public string RegistryPath
    {
      set
      {
        m_regPath = value;
      }
      get
      {
        return m_regPath;
      }
    }

    public bool AllowSaveMinimized
    {
      set
      {
        m_allowSaveMinimized = value;
      }
    }

    private void OnResize(object sender, System.EventArgs e)
    {
      // save width and height
      if (m_parent.WindowState == FormWindowState.Normal)
      {
        m_normalWidth = m_parent.Width;
        m_normalHeight = m_parent.Height;
      }
    }

    private void OnMove(object sender, System.EventArgs e)
    {
      // save position
      if (m_parent.WindowState == FormWindowState.Normal)
      {
        m_normalLeft = m_parent.Left;
        m_normalTop = m_parent.Top;
      }
      // save state
      m_windowState = m_parent.WindowState;
    }

    private void OnClosing(object sender, System.ComponentModel.CancelEventArgs e)
    {
      // save position, size and state
      RegistryKey key = Registry.CurrentUser.CreateSubKey(m_regPath);
      key.SetValue("Left", m_normalLeft);
      key.SetValue("Top", m_normalTop);
      key.SetValue("Width", m_normalWidth);
      key.SetValue("Height", m_normalHeight);
      key.SetValue("ShowErrors", m_parent.ShowErrors);
      key.SetValue("ShowWarnings", m_parent.ShowWarnings);

      // check if we are allowed to save the state as minimized (not normally)
      if (!m_allowSaveMinimized)
      {
        if (m_windowState == FormWindowState.Minimized)
          m_windowState = FormWindowState.Normal;
      }

      key.SetValue("WindowState", (int)m_windowState);

      // fire SaveState event
      if (SaveStateEvent != null)
        SaveStateEvent(this, key);
    }

    private void OnLoad(object sender, System.EventArgs e)
    {
      // attempt to read state from registry
      RegistryKey key = Registry.CurrentUser.OpenSubKey(m_regPath);
      if (key != null)
      {
        int left = (int)key.GetValue("Left", m_parent.Left);
        int top = (int)key.GetValue("Top", m_parent.Top);
        int width = (int)key.GetValue("Width", m_parent.Width);
        int height = (int)key.GetValue("Height", m_parent.Height);
        FormWindowState windowState = (FormWindowState)key.GetValue("WindowState", (int)m_parent.WindowState);

        m_parent.Location = new Point(left, top);
        m_parent.Size = new Size(width, height);
        m_parent.WindowState = windowState;

        bool showErrors = bool.Parse(key.GetValue("ShowErrors", "True").ToString());
        bool showWarnings = bool.Parse(key.GetValue("ShowWarnings", "False").ToString());
        m_parent.ShowErrors = showErrors;
        m_parent.ShowWarnings = showWarnings;
        
        // fire LoadState event
        if (LoadStateEvent != null)
          LoadStateEvent(this, key);
      }
    }
  }
}
